package bancosys.tec.security.impl.domain;

import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

import jmine.tec.persist.annotation.DiscriminatorComment;

import org.apache.commons.lang.builder.HashCodeBuilder;
import org.hibernate.util.EqualsHelper;

import bancosys.tec.component.Documentation;
import bancosys.tec.persist.authorization.annotation.DisplayName;
import bancosys.tec.security.authorization.ActionPermission;
import bancosys.tec.security.authorization.Permission;

/**
 * Credencial que representa uma ação de um bean (edit, remove, list etc).
 * 
 * @author piercio
 */
@Entity
@DiscriminatorValue("4")
@DiscriminatorComment("ACTION")
@DisplayName("Credencial Acao")
public class ActionCredential extends Credential {

    // numero impar qquer
    private static final int HASH_RANDOM_1 = 17;

    // numero impar diferente do primeiro qquer
    private static final int HASH_RANDOM_2 = 43;

    private String action;

    /**
     * Contrutor.
     */
    ActionCredential() {
        // não faz nada
    }

    /**
     * Contrutor.
     * 
     * @param action a ação representada por essa credencial. Deve seguir o padrão 'bean.action' onde bean é o nome do bean a qual a ação
     * action está associada. Para designar qualquer bean (ou qualquer ação de um bean) pode-se usar * no lugar do bean (action), como por
     * exemplo: *.edit, praca.* ou *.* para acesso total.
     */
    public ActionCredential(String action) {
        if (action == null || "".equals(action)) {
            throw new IllegalArgumentException("Ação deve ser informado.");
        }
        if (action.indexOf(".") == -1) {
            throw new IllegalArgumentException("Ação deve ser do formato 'bean.action'.");
        }

        this.action = action;
    }

    /**
     * Devolve a acao representada por essa credencial.
     * 
     * @return a acao representada por essa credencial.
     */
    @Column(name = "ACTION")
    @Documentation("NOME DA ACAO QUE A CREDENCIAL DE ACTION REPRESENTA.")
    public String getAction() {
        return this.action;
    }

    /**
     * Define a acao representada por essa credencial.
     * 
     * @param action a acao representada por essa credencial.
     */
    public void setAction(String action) {
        this.action = action;
    }

    /**
     * Compara esse objeto com o passado como parâmetro. Utiliza a acao como critério de comparação.
     * 
     * @param obj o outro objeto.
     * @return <code>true</code> se forem iguais, <code>false</code> caso contrário.
     */
    @Override
    public boolean equals(Object obj) {
        if (!super.equals(obj)) {
            return false;
        }

        if (!(obj instanceof ActionCredential)) {
            return false;
        }
        ActionCredential other = (ActionCredential) obj;

        if (!EqualsHelper.equals(other.action, this.action)) {
            return false;
        }
        if (!EqualsHelper.equals(other.getClient(), this.getClient())) {
            return false;
        }
        return true;
    }

    /**
     * Devolve o hashCode.
     * 
     * @return o hashCode.
     */
    @Override
    public int hashCode() {
        int superHash = super.hashCode();
        HashCodeBuilder hashCodeBuilder = new HashCodeBuilder(HASH_RANDOM_1, HASH_RANDOM_2);
        hashCodeBuilder.appendSuper(superHash);
        hashCodeBuilder.append(this.getClient().getName());
        hashCodeBuilder.append(this.action);
        return hashCodeBuilder.toHashCode();
    }

    /**
     * Devolve a representação desse objeto.
     * 
     * @return a representação desse objeto.
     */
    @Override
    public String toString() {
        return "ActionCredential (" + this.action + ")";
    }

    /**
     * @return cria uma {@link ActionPermission}
     */
    @Override
    public Permission createPermission() {
        return new ActionPermission(this.getAction());
    }

}
